/******************************************************************************* * Copyright (c) 2006-2013 The RCP Company and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * The RCP Company - initial API and implementation *******************************************************************************/ package com.rcpcompany.uibindings.internal.decorators; import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.databinding.observable.Observables; import org.eclipse.core.databinding.observable.list.IObservableList; import org.eclipse.emf.common.util.Enumerator; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EEnum; import org.eclipse.emf.ecore.EEnumLiteral; import com.rcpcompany.uibindings.Constants; import com.rcpcompany.uibindings.IEnumDecoratorProvider; import com.rcpcompany.uibindings.IEnumDecoratorProviderEntry; import com.rcpcompany.uibindings.IUIBindingDecorator; import com.rcpcompany.uibindings.IValueBinding; import com.rcpcompany.uibindings.decorators.SimpleUIBindingDecorator; import com.rcpcompany.utils.logging.LogUtils; /** * The decorator for enumerations. */ public class EnumBindingDecorator extends SimpleUIBindingDecorator implements IUIBindingDecorator { /** * The provider. */ private final IEnumDecoratorProvider myProvider; /** * @param provider the provider */ public EnumBindingDecorator(IEnumDecoratorProvider provider) { myProvider = provider; } /** * Mapping UI to model with all the defined mappings. */ protected final Map<String, String> uiToModelMappings = new HashMap<String, String>(); /** * The sequence of the ui elements. */ protected final List<String> uiSequence = new ArrayList<String>(); /** * Mapping model to UI with all the defined mappings.. */ protected final Map<String, String> modelToUIMappings = new HashMap<String, String>(); private EEnum myEnumeration; @Override public void init(IValueBinding binding) { super.init(binding); final EClassifier attributeType = binding.getDataType().getEType(); if (!(attributeType instanceof EEnum)) { getBinding().addErrorCondition("Attribute is not an enumeration"); return; } myEnumeration = (EEnum) attributeType; for (final IEnumDecoratorProviderEntry e : myProvider.getBaseMappings()) { final String uiValue = e.getUi(); final String modelValue = e.getModel(); uiToModelMappings.put(uiValue, modelValue); uiSequence.add(uiValue); if (!modelToUIMappings.containsKey(modelValue)) { modelToUIMappings.put(modelValue, uiValue); } } if (myProvider.isAddingDefaultMappings()) { for (final EEnumLiteral e : myEnumeration.getELiterals()) { final String modelValue = e.getName(); final String uiValue = e.getLiteral(); uiToModelMappings.put(uiValue, modelValue); uiSequence.add(uiValue); if (!modelToUIMappings.containsKey(modelValue)) { modelToUIMappings.put(modelValue, uiValue); } } } } @Override public IObservableList getValidUIList() { if (!calculatedValidUIList) { // If the valid values is specified, then use these myValidUIList = getBinding().getArgument(Constants.ARG_VALID_VALUES, IObservableList.class, null); if (myValidUIList == null) { // Otherwise use a list with the currently defined UI to model key myValidUIList = Observables.staticObservableList(uiSequence, String.class); } calculatedValidUIList = true; } return myValidUIList; } @Override protected Object convertModelToUI(Object fromObject) { final String key; if (fromObject == null) return ""; else if (fromObject instanceof Enumerator) { key = ((Enumerator) fromObject).getName(); } else { key = fromObject.toString(); } if (!modelToUIMappings.containsKey(key)) throw new IllegalArgumentException("Cannot map enumeration value '" + fromObject + "'"); return modelToUIMappings.get(key); } @Override protected Object convertUIToModel(Object fromObject) { if (fromObject == null || fromObject.equals("")) return null; String key = fromObject.toString(); if (!uiToModelMappings.containsKey(key)) { /* * Check if a case-insensitive match exists */ String nearMatch = null; for (final String n : uiToModelMappings.keySet()) { if (n.equalsIgnoreCase(key)) { if (nearMatch == null) { nearMatch = n; } else throw new IllegalArgumentException(MessageFormat.format("Illegal value ''{0}''", fromObject)); } } if (nearMatch == null) throw new IllegalArgumentException(MessageFormat.format("Illegal value ''{0}''", fromObject)); key = nearMatch; } final String name = uiToModelMappings.get(key); if (name == null) return null; final EEnumLiteral literal = myEnumeration.getEEnumLiteral(name); if (literal == null) { LogUtils.error(EnumBindingDecorator.this.myProvider.getProviderCE(), "Mapping to unknown enumeration value: '" + name + "'", getBinding().getCreationPoint()); throw new IllegalArgumentException(MessageFormat.format("Illegal value ''{0}''", fromObject)); } return literal.getInstance(); } }